<?php

class APP_Model extends CI_Model {

    public $table;
    public $where = array();
    public $order = array();
    public $join = array();
    public $select = array();
    public $columns_op = array();
    var $operation = false;
    public $search_types = array(
        'l' => 'like',
        'w' => 'where',
        'wn' => 'where_in',
        'wo' => 'or_where'
    );
    public $data = array();

    function __construct() {
        parent::__construct();

        $CI = &get_instance();
    }

    public function is_found($where = array(), $order = array(), $type = FALSE, $url = FALSE, $messgae = FALSE) {
        $fields = $this->db->list_fields($this->table);
        if (!$messgae) {
            $messgae = 'message_no_data_found';
        }

        if (count($order)) {
            $this->orderby($order);
        }

        if ($where) {
            foreach ($where as $key => $value) {
                if (in_array($key, $fields))
                    $key = $this->table . '.' . $key;
                if (is_array($value))
                    $this->db->where_in($key, $value);
                else
                    $this->db->where($key, $value);
            }
        }

        if ($this->where) {
            $this->db->where($this->where);
        }

        if ($this->join) {
            $this->join($this->join);
        }

        if ($this->select) {
            $this->db->select($this->select);
        }

        $sql = $this->db->get($this->table);
        if ($sql->num_rows()) {
            if ($type && in_array($type, array('row', 'result'))) {
                return $sql->$type();
            } else {
                if ($sql->num_rows() > 1) {
                    return $sql->result();
                } else {
                    return $sql->row();
                }
            }
        } else {

            $data = array(
                'url' => $url,
                'type' => 'error',
                'message' => $messgae
            );
            $this->themes->set_message($data);
        }
    }

    public function orderby($order, $type = '') {
        if (!is_array($order)) {
            $order = array($order => $type);
        }
        foreach ($order as $key => $type) {
            $this->db->order_by($key, $type);
        }
    }

    public function join($table, $condition = '', $type = 'INNER') {
        $join = $table;
        if (!is_array($join)) {
            $join = array($table => $condition);
        }
        foreach ($join as $table => $condition) {
            $this->db->join($table, $condition, $type);
        }
    }

    public function beforedelete($param = array()) {
        return true;
    }

    public function afterdelete($param = FALSE) {
        return TRUE;
    }

    public function beforesave($param = FALSE) {
        return TRUE;
    }

    public function aftersave($param = FALSE) {
        return TRUE;
    }

    public function aftertrash($param = FALSE) {
        return TRUE;
    }

    public function save($data = array(), $where = array(), $update = false) {
        $fields = $this->db->list_fields($this->table);
        $this->data = $data;

        foreach ($data as $key => $value) {
            if (in_array($key, $fields))
                $this->db->set($this->table . '.' . $key, $value);
        }
        $time = date("Y-m-d H:i:s");
        if ($update) {
            if (in_array('modify_date', $fields))
                $this->db->set($this->table . '.modify_date', $time);
            foreach ($where as $culm => $value) {
                if (is_array($value)) {
                    $this->db->where_in($culm, $value);
                } else {
                    $this->db->where($culm, $value);
                }
            }
            $this->operation = $this->db->update($this->table);
            $id = TRUE;
        } else {
            if (in_array('create_date', $fields))
                $this->db->set($this->table . '.create_date', $time);
            if (in_array('modify_date', $fields))
                $this->db->set($this->table . '.modify_date', $time);
            $this->operation = $this->db->insert($this->table);
            $id = $this->db->insert_id();
            $this->session->set_userdata('tempid', $id);
        }
        $this->aftersave($id);
        if ($this->operation)
            return $id;
        else
            return $this->operation;
    }

    /**
     * 
     * @param type $where
     * @param type $truncate
     * @return boolean
     */
    public function delete($where = array(), $trash = TRUE, $truncate = false, $or_where = array()) {
        if ($trash) {
            $this->db->set('trash', 'YES');
            if (count($where)) {
                foreach ($where as $column => $values)
                    if (is_array($values)) {
                        $this->db->where_in($column, $values);
                    } else {
                        $this->db->where($column, $values);
                    }
            }

            if (count($or_where)) {
                foreach ($or_where as $column => $values)
                    if (is_array($values)) {
                        $this->db->or_where_in($column, $values);
                    } else {
                        $this->db->or_where($column, $values);
                    }
            }
            $this->operation = $this->db->update($this->table);
            $this->aftertrash($where, $or_where);
        } elseif ($truncate) {
            $this->beforedelete($where, $truncate);
            $this->operation = $this->db->truncate($this->table);
            $this->afterdelete($where, $truncate);
        } else {
            $this->beforedelete($where, $truncate);
            if ($where) {
                foreach ($where as $column => $values) {
                    if (is_array($values)) {
                        $this->db->where_in($column, $values);
                    } else {
                        $this->db->where($column, $values);
                    }
                }

                $this->operation = $this->db->delete($this->table);
                $this->afterdelete($where, $truncate);
            } else {
                return false;
            }
        }

        return $this->operation;
    }

    /**
     * by 
     * @param type $type 2
     * @param type $limit
     * @param type $offset
     * @return type
     */
    public function get($where = false, $count = FALSE, $type = 'result', $limit = FALSE, $offset = FALSE, $trash = false, $order = false, $all = false) {

        $fields = $this->db->list_fields($this->table);
        if (in_array('trash', $fields) && !$all) {
            if ($trash) {
                $this->db->where($this->table . '.trash', 'YES');
            } else {
                $this->db->where($this->table . '.trash', 'NO');
            }
        }

        if ($where) {
            foreach ($where as $key => $value) {
                if (in_array($key, $fields))
                    $key = $this->table . '.' . $key;
                if (is_array($value))
                    $this->db->where_in($key, $value);
                else
                    $this->db->where($key, $value);
            }
        }

        if ($limit) {
            $this->db->limit($limit);
            $this->db->offset($offset);
        }



        if ($this->where)
            $this->db->where($this->where);

        if ($this->join)
            $this->join($this->join);
        if ($order) {
            $this->orderby($order);
        } else {
            if ($this->order)
                $this->orderby($this->order);
        }
        if ($this->select)
            $this->db->select($this->select);

        $result = $this->db->get($this->table);
        if ($count) {
            return $result->num_rows();
        } else {
            if ($type && in_array($type, array('row', 'result'))) {
                return $result->$type();
            }
        }
    }

    public function incrment($where = FALSE) {
        if ($where) {
            foreach ($where as $key => $value) {
                if (is_array($value))
                    $this->db->where_in($key, $value);
                else
                    $this->db->where($key, $value);
            }
        }
        $this->db->set($this->table . '.view', $this->table . '.view + 1', FALSE);
        $this->operation = $this->db->update($this->table);
        return $this->operation;
    }

}

?>
